#define 		MYMAIN_C

#include		"ipmsg.h"
#include 		"MyIpmsg.h"
/*---------------------------------全局变量定义------------------------------------------------*/
char			buffer[MAXSOCKBUF*2];
char 			hostname[HOSTNAME_LENGTH];
char 			buff[8192];
char 			* user = NULL;
char 			* group = NULL;
int 			soc;
struct sockaddr_in 	me;
struct sockaddr_in 	me_tcp;
struct sockaddr_in 	from;
socklen_t 			fromlen;
int 			ipmsgport = DEFAULTPORT;
char 			bcastaddrstr[] = "255.255.255.255";
struct 			ipmsguser *head=NULL,*tail=NULL;
struct sockaddr_in 	bcast;
pthread_t 		id;		/*用于网络监控*/
pthread_t 		id_getfiles;	/*用于建立TCP链接，进行文件传输*/
pthread_t 		id_sendfiles;	/*发送文件/文件夹*/
int 			trans_file_socs[8];	/*最多只能同时8个socket进行文件传输*/
struct sockaddr_in 	trans_file_from[8];	/*8个用户同时向本机传文件*/
transfileheader 	files[MAXTRANSFILENUM];
int 			filenum;
ipmsgdata 		* datafortcp;
unsigned int 		pocketnos;		/*用来记录发送出去的包的编号，用来和返回的数据包的编号进行核对*/
int 			sendcheckflag;		/*标记发送命令中是否含有发送检查标志，1为含有，0为不含*/
int 			repeatflag;			/*是否重发标志*/
int 			recvflag = 0;
int			arrivetimeflag = 0;	/*检查是否到时，以确定是否重发*/
int			startsendflag = 0;	/*开始发送标志*/
int			FileID;			/*记录对方请求发送的文件号*/
/*----------------------------------------------------------------------------------------------*/

void sig_int(int signo)
{
	if (signo == SIGINT) {
		write(1, "\n", 1);
		rl_point = 0;
		rl_end = 0;
		rl_forced_update_display();
	}
}

/*------------------------------------主函数------------------------------*/
int main(int argc, char *argv[])
{
	char 	*cmd/*[MAXCOMMANDLINELEN]*/;
	int 	res;
	struct sigaction sigact;

	sigact.sa_handler = sig_int;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	
	setbuf(stdout, NULL);
	memset(&me_tcp, 0, sizeof(me_tcp));
	me_tcp.sin_family = AF_INET;
	me_tcp.sin_addr.s_addr = htonl(INADDR_ANY);
	me_tcp.sin_port = htons(ipmsgport);
	res = pthread_create(&id, NULL, watch_net, 0);
	if (res != 0) {
		perror("Create thread failed!\n");
		exit(1);
	}
	
	while (1) {
		//printf("(ipmsg)");
		cmd = readline("(ipmsg)");
		//fgets(cmd, MAXCOMMANDLINELEN, stdin);
		//cmd[strlen(cmd)-1] = '\0';
		printf("%s", cmd);
		if (!cmd)
			break;
		if (cmd[0] == '\0')
			continue;
		add_history(cmd);
		if (!command(cmd)) {
			free(cmd);
			break;
		}
		free(cmd);
	}
	
	return 0;
}

/*输入命令*/
int command(char * cmd)
{
	ipmsg_user_list * p=NULL;
	int 		num=0;
	int 		res;
	char   		* tt=NULL;
	char 		* argvs[30] = {NULL};
	int 		i,j;
	void 		* pthread_result;
	int 		argnums;
	sendfilearg 	*arg = NULL;
	size_t		olds = 0;
	struct stat	buf;
	
	olds = 0;
	tt = mystrtok(cmd, " \t", &olds);
	i = 0;
	
	while (1) {
		if (tt == NULL)
			break;
		argvs[i] = strdup(tt);
		i++;
		tt = mystrtok(NULL, " \t", &olds);
	}
	olds = 0;
	argnums = i;
	
	if ( (!strcmp(argvs[0], "list")) || (!strcmp(argvs[0], "l"))) {
		printf("-----------------------------------------------------------------------------------------------------------\n");
		printf("%4s|%20s|%20s|%20s|%s\n", "序号", "用户名", "工作组", "主机名", "IP");
		printf("----|--------------------|--------------------|--------------------|---------------------------------------\n");
		p = head;
		p = p->next;
		while (p){
			p->user_num = num;
			num++;
			printf("%4u|%20s|%20s|%20s|%s\n", (unsigned int) p->user_num, p->user_name, p->user_group, p->user_machine, (char *) inet_ntoa(p->user_addr.sin_addr));
			printf("----|--------------------|--------------------|--------------------|---------------------------------------\n");
			p = p->next;
		}
		return 1;
	}
	
	if (!strcmp(argvs[0], "exit")) {
		ipmsgsendbcast( &bcast, IPMSG_BR_EXIT, NULL);
		if (startsendflag == 1) {
			printf("Sending files,can't exit!\n");
			return 1;
		}
		close(soc);
		return 0;
	}
	
	if (!strcmp(argvs[0], "help")) {
		printf("list or l- for list the users who is online\n");
		printf("refresh - for refresh the ipmsg\n");
		printf("writeto - for send message to somebody or all the user who is online\n");
		printf("read - for read the message which somebody send to you\n");
		printf("sendfile - for send file or folder to somebody,\n");
		printf("	   with the format as follow:\n");
		printf("	   sendfile file(directory) IP(serial number)");
		printf("getfiles - for get files or folder from somebody\n");
		printf("exit - for exit ipmsg\n");
		printf("help - for get help\n");
		printf("clear - for clear the screen\n");
		return 1;
	}
	
	if (!strcmp(argvs[0], "clear")) {
		printf("%c[2J", 0x1b);		/*清除屏幕*/
		printf("%c[0;0H", 0x1b);	/*把光标移动到(0,0)位置*/
		return 1;
	}
	
	if (!strcmp(argvs[0], "getfiles")) {
		if (!filenum) {
			printf("There is no file waiting for being got!\n");
			return 1;
		}
		
		res = pthread_create( &id_getfiles, NULL, getfiles, (void *) datafortcp);
		if (res != 0) {
			perror("Create thread failed!\n");
			exit(1);
		}
		
		if(pthread_join(id_getfiles, &pthread_result) != 0) {
			perror("Join thread failed!\n");
			exit(1);
		}
		filenum--;
		return 1;
	}
	
	
	if (!strcmp(argvs[0], "refresh") && argvs[1] == NULL) {
		del_all_user();
		ipmsgsendbcast( &bcast, IPMSG_NOOPERATION, NULL);
		ipmsgsendbcast( &bcast, IPMSG_BR_ENTRY, NULL);
		return 1;
	}
	
	if (!strcmp(argvs[0], "writeto")) {
		if (argvs[1] == NULL) {
			printf("\"writeto\" needs arg(\"number\" or \"all\" or \"IP\")\n");
			return 1;
		}
		else {
			if (strcmp(argvs[1], "all") && argvs[2] == NULL)	/*writeto 的参数为all的情况*/
				return 1;
			else if (strlen(argvs[1]) <= 4 && argvs[2] == NULL)	/*writeto 的参数为序号时*/
				return 1;
			else if (argvs[2] == NULL)				/*writeto 的参数为IP时*/
				return 1;
		}
	}
	
	/*----------------------------sendfile--------------------------------------------*/
	if (!strcmp(argvs[0], "sendfile")) {
		if (argvs[1] == NULL) {
			printf("\"sendfile\" needs arg(\"-r\" or \"number\" or \"all\" or \"IP\")\n");
			return 1;
		}
		else {
			arg = (sendfilearg *)malloc(sizeof(sendfilearg));
			arg->filenum = argnums - 2;
			if ( arg->filenum > 20) {
				printf("send too many files!\n");
				return 1;
			}
			for(i = 1, j = 0; i <= argnums - 2; i++, j++)
				strncpy(arg->filename[j], argvs[i], PATH_MAX);
			for (i=0; i < arg->filenum; i++) {
				if (stat(arg->filename[i], &buf) == -1) {
					perror("stat error");
					return 1;
				}
				if (S_ISREG(buf.st_mode))
					arg->fileattr[i] = IPMSG_FILE_REGULAR;
				else if (S_ISDIR(buf.st_mode))
					arg->fileattr[i] = IPMSG_FILE_DIR;
			}
			if (!strcmp(argvs[argnums - 1], "all") && argvs[argnums] == NULL) {	/*向所有在线用户发送文件*/
				arg->flags = 2;
				strncpy(arg->to, argvs[argnums - 1], 20);
				return 1;
			}
			else if (strlen(argvs[argnums - 1]) < 4 && argvs[argnums] == NULL) {	/*向指定序号的用户发送文件*/
				arg->flags = 1;
				strncpy(arg->to, argvs[argnums-1], 20);
				res = pthread_create(&id_sendfiles, NULL, sendfiles, (void *)arg);
				if (res != 0) {
					perror("Create thread failed!\n");
					exit(1);
				}
				/*if (pthread_join(id_sendfiles, &pthread_result) != 0) {
					perror("Join thread failed!\n");
					exit(1);
				}*/
				return 1;
			}
			else if (argvs[argnums] == NULL) {				/*向指定IP的用户发送文件*/
				arg->flags = 3;
				strncpy(arg->to, argvs[argnums - 1], 20);
				res = pthread_create(&id_sendfiles, NULL, sendfiles, (void *)arg);
				if (res != 0) {
					perror("Create thread failed!\n");
					exit(1);
				}
				/*if (pthread_join(id_sendfiles, &pthread_result) != 0) {
					perror("Join thread failed!\n");
					exit(1);
				}*/
				return 1;
			}
		}
	}
	/*---------------------------------sendfiles-----------------------------------------------------------*/
        printf("The command is error.\nPlease input \"help\" for help\n");
	i = 0;
	while (argvs[i]) {
		free(argvs[i]);
		i++;
	}
	return 1;
}
